/******************************************************************************* * Copyright (c) 2016 vogella GmbH and others. All rights reserved. This program * and the accompanying materials are made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, and is * available at http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Simon Scholz <simon.scholz@vogella.com> - initial API and implementation; * Patrik Suzzi <psuzzi@gmail.com> - Bug 491572, 491785, 492749 ******************************************************************************/ package org.eclipse.ui.internal.handlers; import java.util.Arrays; import java.util.Optional; import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ParameterizedCommand; import org.eclipse.core.runtime.Status; import org.eclipse.e4.core.commands.ECommandService; import org.eclipse.e4.ui.bindings.internal.BindingTableManager; import org.eclipse.e4.ui.bindings.internal.ContextSet; import org.eclipse.jface.bindings.Binding; import org.eclipse.jface.bindings.TriggerSequence; import org.eclipse.jface.dialogs.PopupDialog; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.contexts.IContextService; import org.eclipse.ui.handlers.HandlerUtil; import org.eclipse.ui.internal.WorkbenchMessages; import org.eclipse.ui.internal.WorkbenchPlugin; import org.eclipse.ui.keys.IBindingService; /** * Handler, which enables a full screen mode. * * @since 3.5 * */ public class FullScreenHandler extends AbstractHandler { private static final String FULL_SCREEN_COMMAND_ID = "org.eclipse.ui.window.fullscreenmode"; //$NON-NLS-1$ private static final String FULL_SCREEN_COMMAND_DO_NOT_SHOW_INFO_AGAIN_PREF_ID = "org.eclipse.ui.window.fullscreenmode.donotshowinfoagain"; //$NON-NLS-1$ private boolean showInfoPopup; private int timeLastEvent; private FullScreenInfoPopup fullScreenInfoPopup; @Override public Object execute(ExecutionEvent event) { // 493186 skips execution of duplicated event if (checkDuplicatedEvent(event)) { return null; } IWorkbenchWindow window = HandlerUtil.getActiveWorkbenchWindow(event); Shell shell = window.getShell(); IBindingService bindingService = window.getService(IBindingService.class); ECommandService commandService = window.getService(ECommandService.class); BindingTableManager bindingTableManager = window.getService(BindingTableManager.class); IContextService bindingContextService = window.getService(IContextService.class); showInfoPopup = !WorkbenchPlugin.getDefault().getPreferenceStore() .getBoolean(FULL_SCREEN_COMMAND_DO_NOT_SHOW_INFO_AGAIN_PREF_ID); Optional<TriggerSequence> sequence = getKeybindingSequence(bindingService, commandService, bindingTableManager, bindingContextService, FULL_SCREEN_COMMAND_ID); String keybinding = sequence.map(t -> t.format()).orElse(""); //$NON-NLS-1$ shell.setFullScreen(!shell.getFullScreen()); if (shell.getFullScreen()) { String message = WorkbenchMessages.ToggleFullScreenMode_ActivationPopup_Description_NoKeybinding; if (!keybinding.isEmpty()) { message = NLS.bind(WorkbenchMessages.ToggleFullScreenMode_ActivationPopup_Description, keybinding); } if (showInfoPopup) { fullScreenInfoPopup = new FullScreenInfoPopup(shell, PopupDialog.HOVER_SHELLSTYLE, true, false, false, false, false, null, null, message); fullScreenInfoPopup.open(); } } else { if (fullScreenInfoPopup != null) { fullScreenInfoPopup.close(); } } return Status.OK_STATUS; } /** * Check if an event is duplicate, by recording and comparing the time of * the trigger event. Returns true if an event is triggered twice with an * event with the same time */ boolean checkDuplicatedEvent(ExecutionEvent event) { if (event != null && event.getTrigger() != null && event.getTrigger() instanceof Event) { int time = ((Event) event.getTrigger()).time; if (time == timeLastEvent) { return true; } timeLastEvent = time; } return false; } private static class FullScreenInfoPopup extends PopupDialog { private String message; private String messageDoNotShowAgain; public FullScreenInfoPopup(Shell parent, int shellStyle, boolean takeFocusOnOpen, boolean persistSize, boolean persistLocation, boolean showDialogMenu, boolean showPersistActions, String titleText, String infoText, String message) { super(parent, shellStyle, takeFocusOnOpen, persistSize, persistLocation, showDialogMenu, showPersistActions, titleText, infoText); this.message = message; this.messageDoNotShowAgain = WorkbenchMessages.ToggleFullScreenMode_ActivationPopup_DoNotShowAgain; } @Override protected Point getInitialLocation(Point initialSize) { if (getShell().getParent() == null) { return super.getInitialLocation(initialSize); } Rectangle bounds = getShell().getParent().getMonitor().getBounds(); GC gc = new GC(getShell().getDisplay()); int textExtendX = gc.textExtent(message).x; gc.dispose(); return new Point(bounds.x + bounds.width / 2 - textExtendX / 2, bounds.y + bounds.height / 5); } @Override protected Control createDialogArea(Composite parent) { Composite composite = (Composite) super.createDialogArea(parent); Label label = new Label(composite, SWT.NONE); label.setText(message); GridData gd = new GridData(GridData.BEGINNING | GridData.FILL_BOTH); gd.horizontalIndent = PopupDialog.POPUP_HORIZONTALSPACING; gd.verticalIndent = PopupDialog.POPUP_VERTICALSPACING; label.setLayoutData(gd); Button btnDoNotShow = new Button(composite, SWT.CHECK); btnDoNotShow.setText(messageDoNotShowAgain); btnDoNotShow.setSelection(WorkbenchPlugin.getDefault().getPreferenceStore() .getBoolean(FULL_SCREEN_COMMAND_DO_NOT_SHOW_INFO_AGAIN_PREF_ID)); GridData gd2 = new GridData(GridData.BEGINNING | GridData.FILL_BOTH); gd2.horizontalIndent = PopupDialog.POPUP_HORIZONTALSPACING; gd2.verticalIndent = PopupDialog.POPUP_VERTICALSPACING; btnDoNotShow.setLayoutData(gd2); composite.addDisposeListener((e) -> { WorkbenchPlugin.getDefault().getPreferenceStore() .setValue(FULL_SCREEN_COMMAND_DO_NOT_SHOW_INFO_AGAIN_PREF_ID, btnDoNotShow.getSelection()); }); return composite; } } protected Optional<TriggerSequence> getKeybindingSequence(IBindingService bindingService, ECommandService eCommandService, BindingTableManager bindingTableManager, IContextService contextService, String commandId) { TriggerSequence triggerSequence = bindingService.getBestActiveBindingFor(commandId); // FIXME Bug 491701 - [KeyBinding] get best active binding is not // working if (triggerSequence == null) { ParameterizedCommand cmd = eCommandService.createCommand(commandId, null); ContextSet contextSet = bindingTableManager .createContextSet(Arrays.asList(contextService.getDefinedContexts())); Binding binding = bindingTableManager.getBestSequenceFor(contextSet, cmd); if (binding != null) { triggerSequence = binding.getTriggerSequence(); } } return Optional.ofNullable(triggerSequence); } }